package com.cup.bddm.impala.service;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cup.bddm.impala.Constant;
import com.cup.bddm.impala.dao.MerchantDao;
import com.cup.bddm.impala.dao.StreetDao;
import com.cup.bddm.impala.po.MchntBaseInfo;
import com.cup.bddm.impala.po.MchntCouponInfo;
import com.cup.bddm.impala.po.MchntDailyTrans;
import com.cup.bddm.impala.po.MchntInfo;
import com.cup.bddm.impala.po.StreetInfo;
import com.cup.bddm.impala.service.MchntService;
import com.cup.bddm.impala.vo.MchntDailyTransVo;
import com.cup.bddm.impala.vo.MchntInfoVo;
import com.cup.bddm.impala.vo.MchntInterTopVo;
import com.cup.bddm.impala.vo.MchntRankVo;
import com.cup.bddm.impala.vo.MchntRingGrowthVo;
import com.cup.bddm.impala.vo.MchntTopAppVo;
import com.cup.bddm.impala.vo.MchntTransVo;
import com.cup.bddm.impala.vo.MchntUpdateVo;
import com.cup.bddm.util.DateUtil;

@Service
public class MchntService {

	static Logger logger = Logger.getLogger(MchntService.class);

	@Autowired
	private MerchantDao merchantDao;

	@Autowired
	private StreetDao streetDao;

	public MchntInfoVo getMerchantInfo(String mchntCd, String date) {
		logger.info("get merchent info detail,mchntCd=" + mchntCd);
		MchntInfoVo merchantVo = new MchntInfoVo();

		try {

			// 获取商户基本信息
			MchntInfo mchntInfo = merchantDao.getMerchantInfo(mchntCd);

			if (mchntInfo == null) {
				merchantVo.setState(Constant.NOT_EXIST);
				return merchantVo;
			}

			merchantVo.setMerchant(mchntInfo);
			merchantVo.setState(Constant.SUCCESS);

			// 获取当日营销信息
			List<MchntCouponInfo> mars = merchantDao.getMchntCouponInfo(mchntCd, date);
			merchantVo.setMars(mars);

		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			merchantVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			merchantVo.setState(Constant.INTER_ERROR);
		}

		return merchantVo;
	}

	public MchntInterTopVo getTopMchntInStreet(String mchntCd, String type, String date) {
		logger.info("get top merchent trans in street with same mchnt type :" + mchntCd);
		MchntInterTopVo mchntInterTopVo = new MchntInterTopVo();
		try {
			// 获取商户基本信息
			MchntInfo mchntInfo = merchantDao.getMerchantInfo(mchntCd);
			List<MchntDailyTrans> topMerchant = merchantDao.getTopMchntInStrByMcc(mchntInfo.getStreet_cd(), mchntInfo.getMchnt_tp(), date, type);
			mchntInterTopVo.setTop_merchant(topMerchant);
			mchntInterTopVo.setState(Constant.SUCCESS);
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntInterTopVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntInterTopVo.setState(Constant.INTER_ERROR);
		}
		return mchntInterTopVo;
	}

	private void formatTransList(List<MchntDailyTrans> dailyTrans, MchntDailyTransVo transVo, String nearestDate) {

		List<String> dateList = new ArrayList<String>();
		List<BigDecimal> transList = new ArrayList<BigDecimal>();

		String curDate = nearestDate.substring(0, 6) + "01";

		while (Integer.valueOf(curDate) <= Integer.valueOf(nearestDate)) {
			dateList.add(Integer.valueOf(curDate.substring(6, 8)) + "");
			BigDecimal transCount = new BigDecimal("0");
			for (MchntDailyTrans dayTrans : dailyTrans) {
				if (dayTrans.getPdate().equals(curDate)) {
					transCount = dayTrans.getTrans_count();
				}
			}
			transList.add(transCount);

			curDate = DateUtil.getNextDay(curDate);
		}

		transVo.setDaily_list(dateList);
		transVo.setDaily_trans_list(transList);
	}

	public MchntUpdateVo updateMchnts(List<MchntBaseInfo> mchnts) {
		logger.info("insert mchnt info.len=" + mchnts.size());
		MchntUpdateVo mchntUpdateVo = new MchntUpdateVo();
		// 存储商圈代码
		Map<String, String> typeMap = new HashMap<String, String>();
		// 1.以商圈代码为key
		for (MchntBaseInfo mchnt : mchnts) {
			typeMap.put(mchnt.getStreet_cd(), "");
		}
		// 2。清除掉不存在的key
		Map<String, String> streetCdExist = new HashMap<String, String>();
		for (String t : typeMap.keySet()) {
			StreetInfo street = streetDao.getStreetInfo(t);
			if (street != null) {
				// 商户信息中只包含商圈代码，不包含商圈名称
				streetCdExist.put(t, street.getStreet_nm());
			}
		}
		// System.out.println("清除不存在的商圈代码");
		// for(String t : typeMapExist.keySet()) {
		// System.out.println("存在的商圈代码："+t);
		// }
		// 3.清除掉不存在的商圈代码的商户
		List<MchntBaseInfo> streetCdExistList = new ArrayList<MchntBaseInfo>();
		List<MchntBaseInfo> streetCdNotExistList = new ArrayList<MchntBaseInfo>();
		for (MchntBaseInfo mchnt : mchnts) {
			boolean flag = false;
			for (String t : streetCdExist.keySet()) {
				if (mchnt.getStreet_cd().equals(t)) {
					flag = true;
					// 补充商圈名称
					mchnt.setStreet_nm(streetCdExist.get(t));
					// System.out.println("商圈名称：" + typeMapExist.get(t));
					streetCdExistList.add(mchnt);
				}
			}
			if (!flag) {
				streetCdNotExistList.add(mchnt);
			}
		}
		try {
			List<MchntBaseInfo> errorList = merchantDao.updateMchntInfo(streetCdExistList);
			errorList.addAll(streetCdNotExistList);
			if (errorList.size() == mchnts.size()) {
				logger.info("insert mchnt info fail ");
				mchntUpdateVo.setState(Constant.INSERT_FAIL);
				mchntUpdateVo.setError_list(errorList);
			}
			if (errorList.size() > 0) {
				logger.info("insert mchnt info not all success ");
				mchntUpdateVo.setState(Constant.PART_SUCCESS);
				mchntUpdateVo.setError_list(errorList);
			}
			if (errorList.size() == 0) {
				logger.info("insert mchnt info success ");
				mchntUpdateVo.setState(Constant.SUCCESS);
			}
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntUpdateVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntUpdateVo.setState(Constant.INTER_ERROR);
		}
		return mchntUpdateVo;
	}

	public MchntTransVo getMerchantTransInfo(String mchntCd, String date) {
		logger.info("get merchent trans ,mchntCd=" + mchntCd + ", date=" + date);
		MchntTransVo mchntTransVo = new MchntTransVo();
		try {
			// 获取当日交易概览
			MchntDailyTrans dayTrans = merchantDao.getMchntDayTrans(mchntCd, date, "all");
			mchntTransVo.setTrans(dayTrans);
			mchntTransVo.setState(Constant.SUCCESS);
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntTransVo.setState(Constant.INTER_ERROR);
		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntTransVo.setState(Constant.INTER_ERROR);
		}
		return mchntTransVo;
	}

	public MchntDailyTransVo getMerchantDailyTrans(String mchntCd, String type, String date) {
		logger.info("get merchent daily trans ,mchntCd=" + mchntCd + ",type=" + type + ", date=" + date);
		MchntDailyTransVo mchntDailyTransVo = new MchntDailyTransVo();

		try {

			if (type.equals("all")) {

				// 获取当月每日交易笔数
				List<MchntDailyTrans> dailyTrans = merchantDao.getMchntAllDailyTrans(mchntCd, date.substring(0, 6));

				if (dailyTrans.size() == 0) {
					mchntDailyTransVo.setState(Constant.NO_TRANS);
					return mchntDailyTransVo;
				}

				formatTransList(dailyTrans, mchntDailyTransVo, date);

				mchntDailyTransVo.setState(Constant.SUCCESS);

			} else if (type.equals("nfc")) {
				// 获取当月每日交易笔数
				List<MchntDailyTrans> dailyTrans = merchantDao.getMchntNfcDailyTrans(mchntCd, date.substring(0, 6));

				// 当月可能没有NFC交易
				if (dailyTrans.size() == 0) {
					mchntDailyTransVo.setState(Constant.NO_TRANS);
					return mchntDailyTransVo;
				}

				formatTransList(dailyTrans, mchntDailyTransVo, date);
				mchntDailyTransVo.setState(Constant.SUCCESS);

			} else if (type.equals("qrc")) {
				// 获取当月每日交易笔数
				List<MchntDailyTrans> dailyTrans = merchantDao.getMchntQrcDailyTrans(mchntCd, date.substring(0, 6));

				// 当月可能没有二维码交易
				if (dailyTrans.size() == 0) {
					mchntDailyTransVo.setState(Constant.NO_TRANS);
					return mchntDailyTransVo;
				}
				formatTransList(dailyTrans, mchntDailyTransVo, date);
				mchntDailyTransVo.setState(Constant.SUCCESS);

			} else if (type.equals("offline")) {
				// 获取当月每日交易笔数
				List<MchntDailyTrans> dailyTrans = merchantDao.getMchntOfflineDailyTrans(mchntCd, date.substring(0, 6));
				// 当月可能没有交易
				if (dailyTrans.size() == 0) {
					mchntDailyTransVo.setState(Constant.NO_TRANS);
					return mchntDailyTransVo;
				}
				formatTransList(dailyTrans, mchntDailyTransVo, date);

				mchntDailyTransVo.setState(Constant.SUCCESS);
			} else {
				mchntDailyTransVo.setState(Constant.PARA_ERROR);
			}
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntDailyTransVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntDailyTransVo.setState(Constant.INTER_ERROR);
		}
		return mchntDailyTransVo;
	}

	public MchntRingGrowthVo getMerchantRingGrowthInfo(String mchntCd, String type, String date) {
		logger.info("get merchent ring growth info ,mchntCd=" + mchntCd + ",type=" + type + ", date=" + date);
		MchntRingGrowthVo mchntRingGrowthVo = new MchntRingGrowthVo();

		try {

			if (type.equals("nfc")) {
				// 获取环比增长率
				// 获取当日交易概览
				MchntDailyTrans dayTrans = merchantDao.getMchntDayTrans(mchntCd, date, type);
				// 获取前日交易概览
				MchntDailyTrans predayTrans = merchantDao.getMchntDayTrans(mchntCd, DateUtil.getPreday(date), type);

				NumberFormat format = NumberFormat.getPercentInstance();// 获取格式化类实例
				format.setMinimumFractionDigits(2);// 设置小数位

				if (dayTrans == null || dayTrans.getTrans_count().compareTo(new BigDecimal("0")) == 0) {
					mchntRingGrowthVo.setRing_growth(format.format(0.0));
				} else if (predayTrans == null) {
					mchntRingGrowthVo.setRing_growth("1");
				} else {
					BigDecimal curCount = dayTrans.getTrans_count();
					BigDecimal preCount = predayTrans.getTrans_count();

					try {
						BigDecimal addRatio = curCount.subtract(preCount).divide(preCount, 4, BigDecimal.ROUND_HALF_UP);
						mchntRingGrowthVo.setRing_growth(format.format(addRatio.doubleValue()));
					} catch (ArithmeticException e) {
						mchntRingGrowthVo.setRing_growth("1");
					}
				}

				mchntRingGrowthVo.setState(Constant.SUCCESS);

			} else if (type.equals("qrc")) {

				// 获取环比增长率
				// 获取当日交易概览
				MchntDailyTrans dayTrans = merchantDao.getMchntDayTrans(mchntCd, date, type);
				// 获取前日交易概览
				MchntDailyTrans predayTrans = merchantDao.getMchntDayTrans(mchntCd, DateUtil.getPreday(date), type);

				NumberFormat format = NumberFormat.getPercentInstance();// 获取格式化类实例
				format.setMinimumFractionDigits(2);// 设置小数位

				if (dayTrans == null || dayTrans.getTrans_count().compareTo(new BigDecimal("0")) == 0) {
					mchntRingGrowthVo.setRing_growth(format.format(0.0));
				} else if (predayTrans == null) {
					mchntRingGrowthVo.setRing_growth("1");
				} else {
					BigDecimal curCount = dayTrans.getTrans_count();
					BigDecimal preCount = predayTrans.getTrans_count();

					try {
						BigDecimal addRatio = curCount.subtract(preCount).divide(preCount, 4, BigDecimal.ROUND_HALF_UP);
						mchntRingGrowthVo.setRing_growth(format.format(addRatio.doubleValue()));
					} catch (ArithmeticException e) {
						mchntRingGrowthVo.setRing_growth("1");
					}
				}

				mchntRingGrowthVo.setState(Constant.SUCCESS);
			} else {
				mchntRingGrowthVo.setState(Constant.PARA_ERROR);
			}
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntRingGrowthVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntRingGrowthVo.setState(Constant.INTER_ERROR);
		}
		return mchntRingGrowthVo;
	}

	public MchntTopAppVo getMerchantTopAppInfo(String mchntCd, String type, String date) {
		logger.info("get merchent top app info ,mchntCd=" + mchntCd + ",type=" + type + ", date=" + date);
		MchntTopAppVo mchntTopAppVo = new MchntTopAppVo();

		try {

			if (type.equals("nfc")) {

				// 获取TOP APP
				List<String> topApp = merchantDao.getTopMchntNfcApp(mchntCd, date.substring(0, 6));
				mchntTopAppVo.setTop5_app(topApp);
				mchntTopAppVo.setState(Constant.SUCCESS);

			} else if (type.equals("qrc")) {

				// 获取TOP APP
				List<String> topApp = merchantDao.getTopMchntQrcApp(mchntCd, date.substring(0, 6));
				mchntTopAppVo.setTop5_app(topApp);
				mchntTopAppVo.setState(Constant.SUCCESS);

			} else {
				mchntTopAppVo.setState(Constant.PARA_ERROR);
			}
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntTopAppVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntTopAppVo.setState(Constant.INTER_ERROR);
		}
		return mchntTopAppVo;
	}

	public MchntRankVo getMerchantRankInfo(String streetCd, String mchntCd, String type, String date) {
		logger.info("get merchent rank info ,mchntCd=" + mchntCd + ",type=" + type + ", date=" + date);
		MchntRankVo mchntRankVo = new MchntRankVo();

		try {

			if (type.equals("nfc")) {
				// 获取商圈内排名
				Integer rank = merchantDao.getNfcRank(streetCd, mchntCd, date);
				mchntRankVo.setRank(rank);
				mchntRankVo.setState(Constant.SUCCESS);

			} else if (type.equals("qrc")) {
				// 获取商圈内排名
				Integer rank = merchantDao.getQrcRank(streetCd, mchntCd, date);
				mchntRankVo.setRank(rank);
				mchntRankVo.setState(Constant.SUCCESS);
			} else if (type.equals("offline")) {
				// 获取商圈内排名
				Integer rank = merchantDao.getOfflineRank(streetCd, mchntCd, date);
				mchntRankVo.setRank(rank);
				mchntRankVo.setState(Constant.SUCCESS);
			} else {
				mchntRankVo.setState(Constant.PARA_ERROR);
			}
		} catch (RuntimeException e) {
			logger.error("internal sql error!", e);
			mchntRankVo.setState(Constant.INTER_ERROR);

		} catch (Exception e) {
			logger.error("internal error!", e);
			mchntRankVo.setState(Constant.INTER_ERROR);
		}
		return mchntRankVo;
	}
}
